﻿using System;
using System.Management;
using System.Security.Cryptography;
using System.Text;

namespace MachineCodeHelper
{
    public class MachineCodeHelper
    {
        /// <summary>
        /// 获取机器码（系统UUID优先，多硬件信息 fallback）
        /// </summary>
        /// <returns>64位大写十六进制机器码，异常时返回"UNKNOWN_MACHINE"</returns>
        public static string GetMachineCode()
        {
            try
            {
                string identifier = GetSystemUUID()
                                   ?? GetMotherboardSerial()
                                   ?? GetCpuId()
                                   ?? GetHardDiskSerial()
                                   ?? GetFallbackIdentifier();

                // 对最终标识进行SHA256哈希处理，统一格式
                using (var sha256 = SHA256.Create())
                {
                    byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(identifier));
                    StringBuilder sb = new StringBuilder();
                    foreach (byte b in hashBytes)
                    {
                        sb.Append(b.ToString("X2")); // 转换为大写十六进制
                    }
                    return sb.ToString();
                }
            }
            catch
            {
                return "UNKNOWN_MACHINE";
            }
        }

        #region 硬件信息获取方法
        /// <summary>
        /// 获取系统UUID（优先）
        /// 来自Win32_ComputerSystemProduct，通常是设备唯一固化标识
        /// </summary>
        private static string GetSystemUUID()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct"))
            {
                foreach (ManagementObject mo in searcher.Get())
                {
                    var uuid = mo["UUID"]?.ToString().Trim();
                    if (!string.IsNullOrEmpty(uuid) && uuid != "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") // 排除无效UUID
                    {
                        return uuid;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取主板序列号（备用1）
        /// </summary>
        private static string GetMotherboardSerial()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard"))
            {
                foreach (ManagementObject mo in searcher.Get())
                {
                    var serial = mo["SerialNumber"]?.ToString().Trim();
                    if (!string.IsNullOrEmpty(serial))
                    {
                        return serial;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取CPU ID（备用2）
        /// </summary>
        private static string GetCpuId()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT ProcessorId FROM Win32_Processor"))
            {
                foreach (ManagementObject mo in searcher.Get())
                {
                    var cpuId = mo["ProcessorId"]?.ToString().Trim();
                    if (!string.IsNullOrEmpty(cpuId))
                    {
                        return cpuId;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取硬盘序列号（备用3）
        /// </summary>
        private static string GetHardDiskSerial()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_PhysicalMedia"))
            {
                foreach (ManagementObject mo in searcher.Get())
                {
                    var diskSerial = mo["SerialNumber"]?.ToString().Trim();
                    if (!string.IsNullOrEmpty(diskSerial))
                    {
                        return diskSerial;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 最后兜底方案（系统信息组合）
        /// </summary>
        private static string GetFallbackIdentifier()
        {
            // 组合系统版本、用户名、安装日期等信息，尽可能降低重复概率
            return $"{Environment.OSVersion.VersionString}_{Environment.UserName}_{Environment.MachineName}_{GetSystemInstallDate()}";
        }

        /// <summary>
        /// 获取系统安装日期（辅助兜底信息）
        /// </summary>
        private static string GetSystemInstallDate()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT InstallDate FROM Win32_OperatingSystem"))
            {
                foreach (ManagementObject mo in searcher.Get())
                {
                    if (mo["InstallDate"] is DateTime installDate)
                    {
                        return installDate.ToString("yyyyMMddHHmmss");
                    }
                }
            }
            return DateTime.Now.ToString("yyyyMMddHHmmss"); // 若获取失败，用当前时间兜底
        }
        #endregion
    }
}